// 导入elecctron模块
import {
    app,
    ipcMain,
    BrowserWindow,
    dialog,
    Notification,
    shell,
    screen,
    systemPreferences,
    desktopCapturer,
    net
} from 'electron';
// 导入os模块获取设备信息
import * as os from 'os';
// 导入path模块
// import path from 'path';
import { join } from 'path';

// const addonPath = path.join(__dirname, '../../resources/addon');
import { exec, spawn } from 'child_process';
// 导入JS字符编码转换工具。
const fs = require('fs'); //引入node原生fs模块

let win = BrowserWindow.getAllWindows()[0];
// import defaultGateway from 'default-gateway';
// TAG电脑设备信息相关👇
//获取当前网络状态
ipcMain.handle('net_isOnline', () => {
    console.log('net_isOnline', net.isOnline());
    return net.isOnline();
});
// 获取设备信息
ipcMain.handle('get_system_info', async () => {
    let info = {
        hostname: os.hostname(), //返回操作系统的主机名。
        type: os.type(), //返回操作系统名
        platform: os.platform(), //返回操作系统名
        arch: os.arch(), //返回操作系统 CPU 架构，可能的值有 "x64"、"arm" 和 "ia32"。
        release: os.release(), //返回操作系统的发行版本。
        uptime: os.uptime(), //返回操作系统运行的时间，以秒为单位。
        loadavg: os.loadavg(), //返回一个包含 1、5、15 分钟平均负载的数组。
        totalmem: os.totalmem(), //返回系统内存总量，单位为字节。
        freemem: os.freemem(), //返回操作系统空闲内存量，单位是字节。
        cpus: os.cpus(), //返回一个对象数组，包含所安装的每个 CPU/内核的信息：型号、速度（单位 MHz）、时间（一个包含 user、nice、sys、idle 和 irq 所使用 CPU/内核毫秒数的对象）。
        userInfo: os.userInfo(), //返回当前用户的信息
        tmpdir: os.tmpdir(), //返回操作系统的默认临时文件夹。
        net: os.networkInterfaces() //获得网络接口列表。
        // addonPath
    };

    const interfaces = os.networkInterfaces();
    // console.log('🚀 ~ ipcMain.handle ~ interfaces:', interfaces);
    // 遍历网络接口
    Object.keys(interfaces).forEach((interfaceName) => {
        const interfaceInfo = interfaces[interfaceName];

        // 遍历每个接口的 IP 地址
        interfaceInfo?.forEach((detail) => {
            if (detail.family === 'IPv4' && !detail.internal && detail.address && detail.netmask) {
                // 忽略内部（非公共可访问）IP地址
                let netInfo = {
                    ipname: interfaceName, // 网络接口名称
                    address: detail.address, // IP地址
                    netmask: detail.netmask, // 子网掩码
                    mac: detail.mac, // MAC地址
                    cidr: detail.cidr // CIDR表示法
                };
                info = { ...info, ...netInfo };
            }
        });
    });

    return info;
});

// 关机
function shutdown() {
    return new Promise((resolve, reject) => {
        let res = {};
        exec('shutdown -s -t 0', (error, stdout, stderr) => {
            if (error) {
                res = {
                    status: '失败',
                    msg: '关机失败'
                };
                return resolve(res);
            }

            let msg = '关机成功';
            res = {
                status: '成功',
                msg
            };
            return resolve(res);
        });
    });
}
ipcMain.handle('shutdown', async (event) => {
    let res = { ...(await shutdown()) };
    return res;
});

// 电脑设备信息相关👆

//TAG应用相关👇
//获取当前版本
// ipcMain.handle('app-version', () => {
//     return app.getVersion();
// });
// 应用相关👆

// TAG窗口相关👇
// 改变窗口大小
ipcMain.on('window-change', (e, w, h) => {
    win.setMinimumSize(w, h); //必须放上面
    win.setSize(w, h);
    win.center();
});
// 最小化窗口
ipcMain.on('window-minimize', () => {
    if (process.platform == 'darwin') {
        if (win.isFullScreen()) {
            win.setFullScreen(false);
            setTimeout(() => {
                win.minimize();
            }, 1000);
        } else {
            win.minimize();
        }
    } else {
        win.minimize();
    }
});
// 切换全屏
ipcMain.on('window-fullScreen', () => {
    // win.simpleFullScreen = !win.simpleFullScreen;
    // win.maximize()最大化方法只能在 Windows 上使用，且不能隐藏底部导航栏，为了使多平台表现一致，上面使用了全屏控制方法setFullScreen
    // win.maximize()
    win.setFullScreen(true);
    // win.setSimpleFullScreen(true)
});
// 切换为大屏窗口和三分之二窗口
ipcMain.on('window_full_size', (e, isFull) => {
    if (isFull) {
        const { width, height } = screen.getPrimaryDisplay().size;
        win.setSize(width, height);
        win.setPosition(0, 0);
        // win.roundedCorners = false;
    } else {
        let w = Math.ceil((screen.getPrimaryDisplay().size.width * 2) / 3);
        let h = Math.ceil((w * 9) / 16);
        win.setMinimumSize(w, h); //必须放上面
        win.setSize(w, h);
        win.center();
        console.log('窗口恢复原来状态', w, h);
        // win.roundedCorners = true;
    }
    // win.setSimpleFullScreen(true)
});
// 隐藏窗口
ipcMain.on('window-hide', () => {
    win.hide(); //隐藏窗口，开发者工具打开时调用这个方法也好使
    // win.close(); // 开发者工具打开时调用这个方法不好使（因为加了托盘所以用hide不用close）
});
// 关闭窗口
ipcMain.on('window-close', () => {
    win.close(); //隐藏窗口，开发者工具打开时调用这个方法也好使
});
// 窗口切换为最大化状态
ipcMain.on('window-fullMax', () => {
    win.show();
    win.maximize();
});
// 窗口恢复原来状态
ipcMain.on('window-restore', () => {
    // win.show();
    // win.unmaximize();
    console.log('窗口恢复原来状态');
    win.setFullScreen(false);
    // win.setSimpleFullScreen(false)
    // if (process.platform == "darwin") {
    //     win.restore()
    //     win.setMinimumSize(1280, 720); //必须放上面
    //     win.setSize(1280, 720);
    //     win.center();
    // }else{
    //     win.unmaximize();
    // }
});
// 窗口改变背景色
ipcMain.on('window-backgroundColor', (e, color) => {
    win.setBackgroundColor(color);
    // win.shadow = false;
    // win.menuBarVisible = false;
    // win.resizable = false;
    // win.frame = false;
    // win.transparent = true;
});
// 窗口设置鼠标是否可以穿透
ipcMain.on('window-setIgnoreMouseEvents', (e, flag) => {
    if (flag) {
        // 下面这行代表，只有点击事件会穿透窗口，鼠标移动事件仍会触发。
        win.shadow = false;
        win.setIgnoreMouseEvents(true, { forward: true });
    } else {
        win.shadow = true;
        win.setIgnoreMouseEvents(false);
    }
});
// 窗口设置透明度
ipcMain.on('window-setOpcaty', (e, num) => {
    win.setOpacity(num);
});
// 窗口设置是否置顶
ipcMain.on('window-setAlwaysOnTop', (e, flag) => {
    win.setAlwaysOnTop(flag, 'pop-up-menu');
    // win.setAlwaysOnTop(flag,"screen-saver")
    // win.setAlwaysOnTop(flag,"floating")
    // win.setAlwaysOnTop(flag,"modalPanel")
    win.moveTop();
    // 窗口置于顶部
});
// 获取成比例3分之2后的窗口大小
// ipcMain.handle("screen-mainSize", () => {
//     let screenSize = screen.getPrimaryDisplay().size
//     let width = screenSize.width * 2 / 3;
//     let height = width * 9 / 16;
//     console.log('widthwidth',width);
//     return {width,height}
// });
// 窗口相关👆

// TAG进程通信相关👇
// TAGGs
// tagsss
// 渲染进程向主进程发送消息（带参数）
ipcMain.handle('ipc-toMainRenderer', (e, params) => {
    return params;
});
// 进程通信相关👆

// win.webContents.send('toSend', 'whoooooooh!')

// TAG系统通知相关👇
// 主进程内发送系统通知
ipcMain.on('notification-main', (event) => {
    let notification = new Notification({
        title: 'Boss2', // 通知的标题, 将在通知窗口的顶部显示
        subtitle: '重要消息22', // 通知的副标题, 显示在标题下面 macOS
        body: '@所有人 放假22！！！', // 通知的正文文本, 将显示在标题或副标题下面
        silent: false, //在显示通知时是否发出系统提示音false有声音，true没声音
        icon: 'icon_32x32.ico',
        timeoutType: 3000 // 通知的超时持续时间 'default' or 'never'或数字
        // toastXml string (可选) Windows - 自定义的窗口通知描述可取代上面所有属性。 提供完全自定义的设计和通知行为。
    });
    notification.show();
    // 点击系统通知
    notification.on('click', () => {
        alert('点击了主进程系统通知');
    });
});
// 系统通知相关👆

// 文件相关👆
// 打开文件并读取选择的文件目录（多选文件）
async function handleFileOpen() {
    let options = {
        properties: ['multiSelections']
    };
    const { canceled, filePaths, bookmarks } = await dialog.showOpenDialog(options);
    if (canceled) {
        return;
    } else {
        console.log(canceled, filePaths);
        return filePaths;
    }
}
ipcMain.handle('dialog-openFile', handleFileOpen);
// 打开文件家并读取选择的文件夹目录（单选文件夹）
async function handleFolderOpen() {
    let options = {
        properties: ['openDirectory']
    };
    const { canceled, filePaths } = await dialog.showOpenDialog(options);
    console.error(canceled, filePaths);
    if (canceled) {
        return;
    } else {
        return filePaths[0];
    }
}
ipcMain.handle('dialog-openFolder', handleFolderOpen);
// 打开文件并读取选择的文件目录（带参数自定义）
async function handleImageFile() {
    let options = {
        title: '选择图片',
        properties: ['openFile'],
        buttonLabel: '选择',
        filters: [{ name: '图片', extensions: ['jpg', 'jpeg', 'png', 'gif'] }]
    };
    // console.error('options',options);
    const { canceled, filePaths } = await dialog.showOpenDialog(options);
    if (canceled) {
        return;
    } else {
        return filePaths[0];
    }
}
ipcMain.handle('dialog-openImageFile', handleImageFile);
// 读取选择的文件目录保存文件
async function handleFileSave() {
    const { canceled, filePaths } = await dialog.showSaveDialog();
    if (canceled) {
        return;
    } else {
        return filePaths[0];
    }
}
ipcMain.handle('dialog-saveFile', handleFileSave);
// 获取文件默认存放路径
ipcMain.handle('app-getDefaultPath', () => {
    return app.getPath('userData');
});
// 重置文件默认路径
ipcMain.on('app-setDefaultPath', (e, filePath) => {
    // 必须是两条斜杠\\
    // userData是要重置的路径的名称，后面是重置到的具体路径
    app.setPath('userData', filePath);
});
// 打开一个网址
ipcMain.on('shell-openExternal', (e, filePath) => {
    shell.openExternal(filePath);
});
// 打开指定文件夹或者文件
ipcMain.on('shell-openPath', (e, filePath) => {
    shell.openPath(filePath);
});
// 显示指定的文件
ipcMain.on('shell-showFolder', (e, filePath) => {
    shell.showItemInFolder(filePath);
});
// 文件相关👆

// TAG屏幕窗口信息相关👇
// 获取主显示器信息
ipcMain.handle('screen-mainMessage', () => {
    return screen.getPrimaryDisplay();
});
// 获取共享屏幕时的窗口信息
ipcMain.handle('navigatorShare', (event, type) => {
    console.log('navigatorShare', event, type);
    return desktopCapturer.getSources({ types: type });
});
// 获取当前应用窗口ID
ipcMain.handle('navigatorCurrentWindowShare', (e) => {
    console.log('id:', win.getMediaSourceId());
    return win.getMediaSourceId();
});
// 通过 source thumbnail 获取截图
async function getCaptureBySourceThumbnail() {
    if (process.platform !== 'win32') return;
    const sources = await desktopCapturer.getSources({
        types: ['window', 'screen']
        // thumbnailSize: getSize()
    });
    if (!sources || !sources.length) throw new Error('sources 为空');
    console.log('sources[0]', sources[0]);
    return JSON.stringify(sources);
}
ipcMain.handle('navigator-share', getCaptureBySourceThumbnail);
// 主窗口截屏
// 监听渲染进程的截屏请求
// https://www.electronjs.org/zh/docs/latest/api/browser-window#wincapturepagerect-opts
ipcMain.on('screenshot', (event, name) => {
    // const { width, height } = screen.getPrimaryDisplay().workAreaSize;

    // 截取整个窗口的图像
    win.capturePage().then((image) => {
        // const screenshotPath = path.join(app.getPath('pictures'), 'screenshot.png');

        // 将图像保存到文件中
        // require('fs').writeFileSync(screenshotPath, image.toPNG());
        // console.log("截屏路径:", width, height,image,image.toDataURL());
        // 将截屏路径发送回渲染进程
        event.sender.send('screenshot_path', image.toDataURL());
    });
});
// 屏幕窗口信息相关👆

// TAG摄像头麦克风相关👇
// 获取麦克风设备信息授权（windows,macos）
// mediaType string - 可以是 microphone, camera 或 screen.
ipcMain.handle('system-getMediaAccessStatus', (e, mediaType) => {
    // if (process.platform !== "darwin"){
    //     console.log(mediaType,'被拒绝了',systemPreferences.askForMediaAccess(mediaType));
    //     return systemPreferences.askForMediaAccess(mediaType)
    // }else{
    //     return systemPreferences.getMediaAccessStatus(mediaType)
    // }
    return systemPreferences.getMediaAccessStatus(mediaType);
});
// 请求访问麦克风设备（macos）
// mediaType string - 请求的媒体类型，可以是microphone 和 camera
ipcMain.handle('system-askForMediaAccess', (e, mediaType) => {
    return systemPreferences.askForMediaAccess(mediaType);
});
/**
 * systemPreferences.getMediaAccessStatus(mediaType) Windows macOS
 * mediaType string - 可以是 microphone, camera 或 screen.
 * 返回 string - 值可以是 not-determined， granted， denied， restricted 或 unknown。
 * macOS 10.14 Mojave 或更高版本需要授权访问 麦克风 和 摄像头。 macOS 10.15 Catalina 或更高版本需要授权访问 屏幕
 */
ipcMain.handle('mac-screen-allow', (mediaType) => {
    return systemPreferences.getMediaAccessStatus(mediaType);
    // askForMediaAccess
});
// mac系统权限
ipcMain.on('system-permission', (mediaType) => {
    // 检查麦克风权限
    exec('sudo tccutil status Microphone', (error, stdout, stderr) => {
        if (stdout.includes('allowed')) {
            // 如果麦克风权限已经被授权，则直接打开偏好设置
            exec(
                'open "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"'
            );
        } else {
            // 如果麦克风权限未被授权，则弹出提示框提示用户打开权限
            dialog
                .showMessageBox({
                    type: 'warning',
                    message: '请先打开麦克风权限',
                    detail: '在弹出的偏好设置窗口中选择应用程序并勾选麦克风权限后，关闭偏好设置窗口即可继续使用。',
                    buttons: ['打开偏好设置', '取消'],
                    defaultId: 0,
                    cancelId: 1
                })
                .then((result) => {
                    if (result.response === 0) {
                        // 打开偏好设置
                        exec(
                            'open "x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"'
                        );
                    }
                });
        }
    });
});

// 摄像头麦克风相关👆

// TAG本地存储electron-store相关👇
// import Store from 'electron-store';
// Store.initRenderer();
// https://www.wenjiangs.com/package/electron-store2
ipcMain.on('setLocalStore', (e, options, data) => {
    console.log('🚀本地存储数据:', options, data);
    // 存储上传列表数据
    let store = new Store({
        name: 'uploadFileList',
        fileExtension: 'json',
        cwd: app.getPath('userData'), //文件位置,尽量不要动，默认情况下，它将通过遵循系统约定来选择最佳位置。C:\Users\xxx\AppData\Roaming\my-electron\config.json
        // encryptionKey:"aes-256-cbc" ,//对配置文件进行加密
        clearInvalidConfig: true // 发生 SyntaxError  则清空配置,
    });
    // 存对象路径,set()只能存基本值
    // store.set(data);
    // store.set('foo.bar', true);或store.set({'foo.bar': true});
    switch (options.type) {
        case 'set':
            store.set(data);
            // store.set({'foo1': true})
            // store.set({'foo2': true})
            break;
        case 'has':
            store.has(data);
            break;
        case 'delete':
            store.delete(data);
            break;
        case 'store':
            store.store = data;
            break;
        default:
            break;
    }
    // 替换所有数据
    // store.store = data;
    // console.log(store.get('unicorn'));
    console.log('🚀 ~ store:', options.type, app.getPath('userData'));
});
// 获取本地文件存储数据
ipcMain.handle('getLocalStore', (e, options, data) => {
    // 存储上传列表数据
    let store = new Store({
        name: 'uploadFileList',
        fileExtension: 'json',
        cwd: app.getPath('userData'), //文件位置,尽量不要动，默认情况下，它将通过遵循系统约定来选择最佳位置。C:\Users\xxx\AppData\Roaming\my-electron\config.json
        // encryptionKey:"aes-256-cbc" ,//对配置文件进行加密
        clearInvalidConfig: true, // 发生 SyntaxError  则清空配置,
        ...options
    });

    let getData = data ? store.get(data) : store.store;

    // console.log("🚀 ~ getData:", getData);
    return getData;
});
// 读取本地文件
ipcMain.on('asyncGetLocalServer', (event, arg) => {
    let isHavePat = fs.existsSync(arg.path); // 判断文件是否存在
    console.log('判断文件是否存在:', isHavePat, arg);
    // 读入文件 异步返回
    fs.readFile(arg.path, (err, result) => {
        if (err) {
            console.log(err, '读取文件内容失败');
            event.sender.send('asyncBackLocalServer', { fileData: '读取文件失败', ...arg }); // 返回给渲染进程
        } else {
            const fileData = new Uint8Array(Buffer.from(result));
            event.sender.send('asyncBackLocalServer', { fileData, ...arg }); // 返回给渲染进程
            console.log('读取文件内容成功', arg.name);
        }
    });
});
// 本地存储electron-store相关👆
